package com.lyy.server;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Liangyaoyun
 */
@Slf4j
@ServerEndpoint("/danmu/{userId}")
@Component
public class DanMuServer {

    private static final Map<Integer, Session> users = new ConcurrentHashMap<>();

    /**
     * 当WS客户端上线时触发: 将WS客户端的标识信息及其session实例存入Map
     *
     * @param userId  WS客户端唯一标识
     * @param session 每个WS客户端连入WS服务端时，都会生成独有的session对象
     */
    @OnOpen
    public void onOpen(@PathParam("userId") Integer userId, Session session) {
        log.info("{} 号用户上线了", userId);
        users.put(userId, session);
        System.out.println(userId);
    }

    /**
     * 当WS客户端下线时触发
     *
     * @param userId  WS客户端唯一标识
     * @param session 每个WS客户端连入WS服务端时，都会生成独有的session对象
     */
    @OnClose
    public void onClose(@PathParam("userId") Integer userId, Session session) {
        log.info("{} 号用户下线了", userId);
        // 从Map中移除该客户端和及其Session实例
        users.remove(userId);
    }

    /**
     * 当WS客户端连接WS服务端异常时触发
     *
     * @param userId  WS客户端唯一标识
     * @param e       异常实例
     * @param session 每个WS客户端连入WS服务端时，都会生成独有的session对象
     */
    @OnError
    public void onError(@PathParam("userId") Integer userId, Throwable e, Session session) {
        log.error("{} 号用户连接或者通信异常", userId, e);
    }

    /**
     * 当WS服务端接收到消息的时候触发: 对Map中的全部在线的WS客户端群发消息
     *
     * @param userId  WS客户端唯一标识
     * @param msg     消息内容
     * @param session 每个WS客户端连入WS服务端时，都会生成独有的session对象
     */
    @OnMessage
    public void onMessage(@PathParam("userId") Integer userId, String msg, Session session) {
        log.info("{} 号用户发来消息: {}", userId, msg);
        // 遍历Map容器并向所有在线的客户端推送该消息
        users.keySet().forEach(key -> users.get(key).getAsyncRemote().sendText(msg));
    }
}